/******************************************************************************************
 * Import
 ******************************************************************************************/

// module
import _ from 'lodash';
import Taro from '@tarojs/taro';

// project
import Collect from './http/collect';
import Parse from './http/parse';

/******************************************************************************************
 * Export Class
 ******************************************************************************************/

/**
 * 请求设置对象结构：
 * {
 *      url: string,                                        // request url地址,
 *      data: object,                                       // 参数键值对,
 *      success(data)=> {},                                 // 成功回调函数
 *      error(res)=> {}                                     // 逻辑错误回调函数
 *      config: {                                           // 设置对象
 *          debug: boolean,                                 // 是否在console中追踪response，（默认为false）
 *          parse: '',                                      // 解析器设置，可选择已经在库中存在的解析器，默认为hesq
 *          header: object,                                 // 需要携带的header对象
 *          indicator: {                                    // 指示器对象
 *              start() {},                                 // 开始执行动作回调
 *              end() {}                                    // 结束执行动作回调
 *          },
 *          fail: {                                         // 失败对象，对服务端错误、网络错误的统一处理
 *              status(statusCode, setting) {},             // 服务器状态错误处理器
 *              parse(responseText, setting) {},            // 返回值解析错误处理器
 *              format(responseText, setting) {},           // 返回值的格式错误处理器
 *              network(err) {}                             // 网络错误处理器
 *          }
 *      } 
 * }
 */
export default class Http {

    /*------------------------------------------------------------------------------------
	 * 外部调用接口
	 *-----------------------------------------------------------------------------------*/
    /**
     * get请求，参数请看_request方法
     * 
     * @param {Object} setting 访问请求设置对象 
     */
    static get(setting) {
        setting['method'] = 'GET';
        this.request(setting);
    }

    /**
     * post请求，参数请看_request方法
     * 
     * @param {Object} setting 访问请求设置对象 
     */
    static post(setting) {
        setting['method'] = 'POST';
        this.request(setting);
    }

    /**
     * 真实访问方法
     * 
     * @param {String} method 访问方法
     * @param {Object} setting 访问请求设置对象 
     */
    static request(setting) {

        console.log('>>>>>>>>',setting)

        // ------------------------------------------------------ 
        // 取简写
        let {url, method, data, config} = setting;

        // ------------------------------------------------------ 
        // 显示指示器
        if (_.isObject(config) && _.isObject(config.indicator) && _.isFunction(config.indicator.start) && _.isFunction(config.indicator.end)) {
            config.indicator.start();
        }

        // ------------------------------------------------------ 
        // 发起请求，并返回数据
        Taro.request({

            // --------------------------------------------------
            // 基础参数
            url: url,
            data: data,
            method: method,
            header:config.header,
            // --------------------------------------------------
            // 成功处理
            success(res) {

                // 如果打开了debug，则输出response信息
                if (_.isObject(config) && config.debug) {
                    console.log('--------- ' + method + ' : ' + url);
                    if (_.isObject(data)) {
                        console.log(data);
                    }
                    console.log(res);
                    console.log('--------- END');
                }

                // 返回码判断，如果不等于200，则：收集错误，调用错误回调，并直接返回
                if (parseInt(res.statusCode) != 200) {
                    Collect.statusFail(res.statusCode, setting);
                    if (_.isObject(config.fail) && _.isFunction(config.fail.status)) {
                        config.fail.status(res.statusCode, setting);
                    }
                    return;
                }

                // 赋值parse类型
                let parse = 'hesq';
                if (_.isObject(config) && _.isString(config.parse)) {
                    parse = config.parse;
                }

                // 执行解析
                Parse[parse].action(res.data, setting);
            },

            // --------------------------------------------------
            // 失败处理，收集错误，并调用错误回调
            fail(err) {
                Collect.networkFail(err, setting);
                if (_.isObject(config.fail) && _.isFunction(config.fail.network)) {
                    config.fail.network(err, setting);
                } 
            },

            // --------------------------------------------------
            // 统一完成函数，隐藏指示器
            complete() {
                if (_.isObject(config) && _.isObject(config.indicator) && _.isFunction(config.indicator.start) && _.isFunction(config.indicator.end)) {
                    config.indicator.end();
                }
            }
        })
    }
}
